<script setup>
import {reactive, watch, onMounted, onBeforeUnmount, nextTick} from 'vue'
import { getByParams } from '@/net'
import * as echarts from 'echarts'
import {Close} from "@element-plus/icons-vue"
import { ElMessage } from "element-plus"


const props = defineProps({
  clientId: Number // 修正拼写
})

const emit = defineEmits(['close'])

// 时间范围选项
const timeRanges = [
  { label: '1小时', value: 1 },
  { label: '6小时', value: 6 },
  { label: '12小时', value: 12 },
  { label: '1天', value: 24 },
  { label: '3天', value: 72 },
  { label: '7天', value: 168 },
  { label: '14天', value: 336 }
]

// 图表配置
const chartConfig = {
  cpu: {
    title: 'CPU使用率',
    unit: '%',
    key: 'value',  // 对应commonData.value
    aggregateOptions: ['avg', 'max', 'min', 'sum', 'last']
  },
  memory: {
    title: '内存使用量',
    unit: 'GB',
    key: 'value',  // 对应commonData.value
    aggregateOptions: ['avg', 'max', 'min', 'sum', 'last']
  },
  disk: {
    title: '磁盘使用量',
    unit: 'GB',
    key: 'value',  // 对应commonData.value
    aggregateOptions: ['avg', 'max', 'min', 'sum', 'last']
  },
  network: {
    title: '网络传输速率',
    unit: 'KB/s',
    keyField: 'network',  // 对应network数组
    series: [
      { name: '下载', key: 'download' },
      { name: '上传', key: 'upload' }
    ],
    aggregateOptions: ['avg', 'max', 'min', 'sum', 'last']
  },
  diskIO: {
    title: '磁盘IO速率',
    unit: 'KB/s',
    keyField: 'disks',  // 对应disks数组
    series: [
      { name: '读取', key: 'read' },
      { name: '写入', key: 'write' }
    ],
    aggregateOptions: ['avg', 'max', 'min', 'sum', 'last']
  }
}

const state = reactive({
  aggregates: {
    cpu: 'avg',
    memory: 'avg',
    disk: 'avg',
    network: 'avg',
    diskIO: 'avg'
  },
  periods: {
    cpu: '1分钟',
    memory: '1分钟',
    disk: '1分钟',
    network: '1分钟',
    diskIO: '1分钟'
  },
  timeRange: 1,
  customDate: [],
  loading: false,
  chartInstances: {},
  chartOptions: {},
  historyData: {} // 初始化为对象
})

// 初始化图表
const initCharts = () => {
  Object.keys(chartConfig).forEach(type => {
    const dom = document.getElementById(`chart-${type}`)
    if (dom) {
      state.chartInstances[type] = echarts.init(dom)
      setBaseOption(type)
    }
  })
}

// 基础图表配置
const setBaseOption = (type) => {
  const config = chartConfig[type]
  const isMultiSeries = !!config.series

  const option = {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'cross' }
    },
    grid: {
      left: 50,
      right: 30,
      bottom: 30,
      containLabel: true
    },
    xAxis: {
      type: 'time',
      axisLabel: {
        formatter: (value) => {
          const date = new Date(value)
          return echarts.time.format(date, '{MM}/{dd} {HH}:{mm}', false)
        }
      }
    },
    yAxis: {
      name: config.unit,
      nameTextStyle: {
        padding: [0, 30, 0, 0]
      }
    },
    series: isMultiSeries
        ? config.series.map(s => ({
          name: s.name,
          type: 'line',
          smooth: true,
          showSymbol: true,
          animation: false
        }))
        : [{
          type: 'line',
          smooth: true,
          showSymbol: true,
          animation: false
        }]
  }

  state.chartOptions[type] = option
  state.chartInstances[type].setOption(option)
}

// 数据获取方法
const fetchHistory = async (type) => {
  try {
    state.loading = true
    const timeParams = getTimeParams()
    const params = {
      clientId: props.clientId,
      statType: state.aggregates[type].toUpperCase(),
      metricType: metricTypeMapping[type],
      ...timeParams
    }
    getByParams('/api/monitor/history', params, data => {
      console.log(`${type}数据请求成功:`, data)
      state.historyData[type] = handleDataStructure(data, type)
      state.periods[type] = data.period
      updateChart(type)
    })
  } catch (e) {
    console.error(`${type}数据请求失败:`, e)
    ElMessage.error(`${chartConfig[type].title}数据加载失败`)
  } finally {
    state.loading = false
  }
}

// 数据结构处理方法
const handleDataStructure = (data, type) => {
  const config = chartConfig[type]
  const targetKey = metricTypeMapping[type]

  let sourceData = []
  switch(targetKey) {
    case 'DISK-IO':
      // 处理磁盘IO数据聚合
      sourceData = data.disks || []

      break
    case 'NETWORK':
      // 网络数据直接使用
      sourceData = data.network || []
      break
    default:
      // 普通指标数据
      sourceData = data.commonData || []
  }

  // 统一时间格式处理并排序
  return sourceData
      .map(item => ({
        timestamp: new Date(item.timestamp).getTime(),
        ...item
      }))
      .sort((a, b) => a.timestamp - b.timestamp) // 确保数据按时间排序
}

// 图表更新逻辑
const updateChart = (type) => {
  const config = chartConfig[type]
  console.log(`更新${type}图表`,config)
  const instance = state.chartInstances[type]

  // 生成系列数据（带数据过滤）
  const generateSeriesData = (seriesConfig) => {
    return state.historyData[type]
        .filter(d => typeof d[seriesConfig.key] === 'number')
        .map(d => [d.timestamp, d[seriesConfig.key]])
  }
  const option = {
    ...state.chartOptions[type],
    series: config.series
        ? config.series.map(s => ({
          ...s,
          type: 'line',
          animation:false,
          showSymbol:true,
          smooth:true,
          data: generateSeriesData(s)
        }))
        : [{
          ...state.chartOptions[type].series[0],
          data: generateSeriesData({ key: config.key })
        }]
  }
console.log(`${type}图表option`,option)
  instance.setOption(option, { replaceMerge: ['series'] })
}

const getTimeParams = () => {
  let start, end;
  if (state.customDate && state.customDate.length === 2) {
    // 处理Safari兼容性
    const parseDate = (str) => new Date(str.replace(/-/g, '/'));
    start = parseDate(state.customDate[0]);
    end = parseDate(state.customDate[1]);
  } else {
    end = new Date();
    start = new Date(end.getTime() - state.timeRange * 3600 * 1000);
  }

  // 手动拼接本地时间字符串（北京时间，不带时区转换）
  const formatLocalTime = (date) => {
    const pad = (num) => num.toString().padStart(2, '0');
    return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
        `T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
  };

  return {
    start: formatLocalTime(start),
    end: formatLocalTime(end)
  };
};

const metricTypeMapping = {
  cpu: 'CPU',
  memory: 'MEMORY',
  disk: 'DISK',
  network: 'NETWORK',
  diskIO: 'DISK-IO' // 保持和Java枚举一致
}

// 替换原有 disabledDate 函数
const disabledDate = (date) => {
  const now = Date.now();
  return (
      date.getTime() > now || // 禁用未来日期（精确到毫秒）
      date.getTime() < now - 30 * 86400000 // 保留原有 30 天前限制
  );
};

// 刷新数据
const refreshData = () => {
  if (props.clientId) {
    Object.keys(chartConfig).forEach(type => fetchHistory(type))
  }
}

// 窗口resize处理
const handleResize = () => {
  Object.values(state.chartInstances).forEach(instance => {
    instance.resize()
  })
}

// 生命周期钩子
onMounted(() => {
  nextTick(()=>{
    initCharts()
    window.addEventListener('resize', handleResize)
  })

  if (props.clientId) {
    Object.keys(chartConfig).forEach(type => fetchHistory(type))
  }
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
  Object.values(state.chartInstances).forEach(instance => {
    instance.dispose()
  })
})

watch(() => props.clientId, (newVal) => {
  if (newVal) {
    Object.keys(chartConfig).forEach(type => fetchHistory(type))
  }
})

const handleTimeRangeChange = (value) => {
  state.customDate = []
  refreshData() // 直接触发刷新
}

const handleCustomDateChange = (val) => {
  if (val && val.length === 2) {
    state.timeRange = null
    refreshData() // 直接触发刷新
  }
}
</script>

<template>
  <div class="history-container">
    <div class="control-bar">
      <div class="header-wrapper">
        <div class="title">
          <i class="fa-solid fa-clock-rotate-left"></i>
          主机历史监控
          <el-button
              type="primary"
              :loading="state.loading"
              @click="refreshData"
              size="small"
              class="refresh-btn"
          >
            刷新
          </el-button>
        </div>
        <el-button
            type="danger"
            plain
            @click="emit('close')"
            class="close-btn"
        >
          <el-icon><Close /></el-icon>
          <span style="margin-left: 8px">关闭</span>
        </el-button>
      </div>

      <div class="filter-controls">
        <el-radio-group v-model="state.timeRange" @change="handleTimeRangeChange">
          <el-radio-button
              v-for="tr in timeRanges"
              :key="tr.value"
              :label="tr.value"
          >
            {{ tr.label }}
          </el-radio-button>
        </el-radio-group>

        <el-date-picker
            v-model="state.customDate"
            type="daterange"
            value-format="YYYY-MM-DD HH:mm:ss"
            format="YYYY-MM-DD HH:mm:ss"
            :disabled-date="disabledDate"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            @change="handleCustomDateChange"

        />
      </div>
    </div>

    <div class="chart-container">
      <div class="chart-item" v-for="(config, type) in chartConfig" :key="type">
        <div class="chart-header">
          <h3>{{ config.title }} ({{ config.unit }})</h3>
          <div class="chart-controls">
            <el-select
                v-model="state.aggregates[type]"
                style="width: 120px"
                @change="fetchHistory(type)"
            >
              <el-option
                  v-for="opt in config.aggregateOptions || ['avg', 'max', 'min', 'sum', 'last']"
                  :key="opt"
                  :label="opt.toUpperCase()"
                  :value="opt"
              />
            </el-select>
            <span class="period-text">
              周期：{{ state.periods[type] }}
            </span>
          </div>
        </div>
        <div :id="`chart-${type}`" class="chart-wrapper"></div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.history-container {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.control-bar {
  margin-bottom: 20px;
}

.header-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 18px;
  color: #409EFF;
}

.refresh-btn {
  margin-left: 15px;
  font-weight: normal;
  padding: 7px 15px;
}

.period-text {
  color: #67C23A;
  font-size: 13px;
  margin-left: 12px;
  letter-spacing: 1px;
}

.filter-controls {
  display: flex;
  gap: 15px;
  align-items: center;
  flex-wrap: wrap;
}

.chart-container {
  flex: 1;
  overflow-y: auto;
  padding-right: 10px;
}

.chart-item {
  background: transparent;
  box-shadow: none;
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.chart-header h3 {
  margin: 0;
  font-size: 16px;
  color: #409EFF; /* 蓝色 */
}

.chart-wrapper {
  height: 300px;
  width: 100%;
  min-height: 200px;
}

.close-btn {
  margin-left: auto;
}

.chart-controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

:deep(.echarts) .xAxis line,
:deep(.echarts) .yAxis line {
  stroke: #ccc;
}

:deep(.echarts) .xAxis text,
:deep(.echarts) .yAxis text {
  fill: #666;
}
</style>